# -*- coding:utf-8 -*-
import json

# @Time    : 2023/5/16 02:21
# @Author  : zengwenjia
# @Email   : zengwenjia@lingxi.ai
# @File    : generate_bot_dialogue.py
# @Software: LLM_internal

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
import pandas as pd
import asyncio
from bot.insurance_consultant.sales import Sales
from bot.insurance_consultant.user import User
import uuid
from data_generate import utils
import traceback
import random
from loguru import logger


# 用户query模拟生成
async def mock_bot_dialogue_by_query(path, taget_num=1):
    train_data = []
    # 百家姓
    surname = ["赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", "褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许", ]
    sex = [  # '先生',
        '女士']
    addresses = ['包头', '北京', '合肥', '武汉', '鹤壁', '青岛']
    purposes = [
        # "不接受赠险,表示自己不需要,不坐飞机",
        #"不接受赠险,态度强硬,对销售员发出质疑",
        "接受赠险,在销售员带用户操作时,不配合操作,嫌麻烦,让销售员讲清楚操作步骤,中间尝试告诉销售员操作错了中间关闭页面,让销售员带着重新打开重新操作，最终同理领取赠险，同意购买百万医疗险。如果销售员说用户面临的风险,用户表示不认可风险,并表示自己不需要,在销售员带用户进行支付时,操作不熟悉,反反复复操作多次",
        #"接受赠险,对通过手机投保操作非常不熟悉,让销售员讲清楚操作步骤,中间尝试告诉销售员操作错了",
        #"接受赠险,对通过手机投保操作非常不熟悉,让销售员讲清楚操作步骤,中间关闭页面,让销售员带你重新打开重新操作",
        #"接受赠险,并配合销售员操作,在销售员介绍完百万医疗并收集用户信息时,对短险发出质疑,并表示自己不需要",
        #"接受赠险,并配合销售员操作,在销售员介绍完百万医疗并收集用户信息后,如果销售员说用户面临的风险,用户表示不认可风险,并表示自己不需要",
        #"接受赠险,并配合销售员操作,在销售员介绍完百万医疗并收集用户信息后,在销售员主动介绍费用时,表示价格太高,不愿意购买",
        #"接受赠险,并配合销售员操作,在销售员介绍完百万医疗并收集用户信息后,在销售员带用户进行支付时,操作不熟悉,反反复复操作多次",
        #"接受赠险,并配合销售员操作,然后配合销售员投保短险,在销售员推荐给家人投保时,表示自己不需要",
    ]
    professions = [
        # '消防员'
        # '学生',
        '失业',
        '自由职业',
        '家庭主妇',
        '餐饮类',
        '幼儿园老师',
        '初中老师',
        '公务员',
        # '自媒体-主播',
        # '抖音电商',
        # '个体经营者',
        # '货车司机',
        '快递员',
        '工地工人',
        '工厂工人',
        # '商业销售',
        # '医生护士',
        # '银行职员',
        # '金融专家',
        # '程序员',
        # '机械工程师',
        '农民',
        # '养殖业',
    ]
    marriages = [
        # '未婚',
        '已婚',
        '离异',
    ]
    members = [
        '无孩子',
        '有一个孩子',
        '有两个孩子',
        # '有两个孩子女孩',
        # '有一个孩子男孩',
    ]
    user_attitudes = [
        '肯定态度',
        '肯定态度',
        '无态度',
        '否定态度',
        '消极态度'
    ]

    user_questions = get_conversation_template("../data/user_text.csv")
    faq_corpus = get_faq_corpus("../data/341.csv")
    user_questions = user_questions + faq_corpus

    out_writer = open("dialogue_tmp.txt", 'a+')
    for i in range(taget_num):
        name = random.choice(surname) + random.choice(sex)
        age = random.choice(range(20, 70))
        address = random.choice(addresses)
        purpose = random.choice(purposes)
        profession = random.choice(professions)
        marriage = random.choice(marriages)
        member = random.choice(members)
        logger.info('purpose is {purpose}', purpose=purpose)

        try:
            bot = Sales()
            context = []
            instruct_dict_new = {}
            session_id = str(uuid.uuid1())
            instruct_dict_new["id"] = session_id
            instruct_dict_new["messages"] = []
            instruct_dict_new["messages"].append({
                "role": "user",
                "content": "你好。"
            })
            user_base_info = f"姓名:{name}\n年龄:{str(age)}\n'地区':{address}\n职业:{profession}\n婚姻状况:{marriage}\n家庭成员:{member}"
            base_info = f"姓名:{name}\n年龄:{str(age)}\n'地区':{address}"
            logger.info('user base info is {user_base_info}', user_base_info=user_base_info)

            random.shuffle(user_questions)
            condidate_query = '\n'.join(user_questions[:100])

            history = bot.format_conversation_history(context)
            res = await bot.async_reply(history, session_id, name, base_info)
            conversation_dict = {}
            conversation_dict["role"] = "assistant"
            conversation_dict["content"] = res
            instruct_dict_new["messages"].append(conversation_dict)
            context.append(conversation_dict)

            for j in range(50):
                user_attitude = random.choice(user_attitudes)
                history = bot.format_conversation_history(context)
                user = User(user_base_info, condidate_query, history, purpose, user_attitude)
                query = await user.achat_with_proxy_gpt4(save_data=False)
                conversation_dict = {}
                conversation_dict["role"] = "user"
                conversation_dict["content"] = query.strip()
                instruct_dict_new["messages"].append(conversation_dict)
                context.append(conversation_dict)
                mute_count = 0
                for conversation in context:
                    if conversation['role'] == 'user' and conversation['content'] == '@@quiet@@':
                        mute_count += 1
                if mute_count >= 3:
                    res = '那等您方便的时候我们再联系吧，祝您生活愉快，再见！'
                elif query == '@@quiet@@':
                    res = '抱歉哈，没太听清楚，您是本人吗？'
                else:
                    res = await bot.async_reply(context, session_id, name, base_info, content=query.strip())
                    conversation_dict = {}
                conversation_dict["role"] = "assistant"
                conversation_dict["content"] = res
                instruct_dict_new["messages"].append(conversation_dict)
                context.append(conversation_dict)
                logger.info('上下文缓存是 {context}', context=json.dumps(context))
                # history = bot.format_conversation_history(context)

                # user_suggestion_obj = UserSuggestion(conversation_history=history)
                # user_suggestion = await user_suggestion_obj.achat_auto_llm()
                # print(user_suggestion)

                if "再见" in res or "拜拜" in res:
                    break
            train_data.append(instruct_dict_new)
            utils.jdump(train_data, path)
            out_writer.write(str(instruct_dict_new) + "\n")
            out_writer.flush()
        except Exception as e:
            traceback.print_exc()
            # 打印堆栈
            print(e)

    out_writer.close()


def get_faq_corpus(path):
    standard_expand = {}
    df = pd.read_csv(path)
    faqDictList = df.to_dict("records")
    for index, faq in enumerate(faqDictList):
        standard = faq['标准问']
        expand = faq['扩展问']
        if standard == "NOINTENT" or standard == "" or standard == "nan":
            continue
        if standard not in standard_expand:
            standard_expand[standard] = []
        standard_expand[standard].append(expand)

    all_query = []
    for k, v in standard_expand.items():
        random.shuffle(v)
        if len(v) < 50:
            all_query.extend(v)
        elif len(v) < 100:
            all_query.extend(v[:int(len(v) * 0.7)])
        elif len(v) < 200:
            all_query.extend(v[:int(len(v) * 0.6)])
        elif len(v) < 300:
            all_query.extend(v[:int(len(v) * 0.5)])
        elif len(v) < 400:
            all_query.extend(v[:int(len(v) * 0.4)])
        else:
            all_query.extend(v[:int(len(v) * 0.2)])
    random.shuffle(all_query)

    # print(len(all_query))

    return all_query


def get_conversation_template(path):
    df = pd.read_csv(path)
    datas = df.to_dict('records')
    texts = [data['text'] for data in datas]
    return texts


def conversation2csv(file_path):
    datas = utils.jload(file_path)
    df = pd.DataFrame(columns=['角色', '内容'])

    for data in datas:
        messages = data['messages']
        for text in messages:
            df = df._append(
                {"角色": text['role'],
                 "内容": text['content']},
                ignore_index=True)
        df = df.reset_index(drop=True)._append(
            {"角色": "",
             "内容": ""},
            ignore_index=True)
    df.to_csv(file_path.replace('.json', '.csv'))


if __name__ == '__main__':
    import datetime

    for i in range(1):
        now_date = datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S")
        file_path = "../data_set/bot_dialogue/bot_dialogue_" + now_date + ".json"  # 文件夹路径
        asyncio.run(mock_bot_dialogue_by_query(file_path))
        conversation2csv(file_path)

    # get_faq_corpus("/Users/cy/Downloads/222.csv")
